/**
 * PHOSIDE: PHosphorylation Site IDentification Engine.
 * Copyright 2009 Digital Biology Lab, University of Missouri.
 * This library is free software; you can redistribute it and/or modify it under
 * the terms of the GNU General Public License as published by the Free Software
 * Foundation; either version 3 of the License, or (at your option) any later
 * version. <p/> This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the License for more
 * details.
 */

package phoside.model;

import java.beans.PropertyChangeSupport;

import java.io.FileNotFoundException;
import java.io.IOException;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;

import phoside.util.IOUtil;


/**
 *
 * @author gjj
 */
public final class PhosideModelManager {
    private static PhosideModelManager manager;

    static {
        manager = new PhosideModelManager();
    }

    public static PhosideModelManager getManager() {
        return manager;
    }

    private PropertyChangeSupport pcs;
    private Map<String,List<PhosideModel>> mapFileModels;


    public static final String FILE_ADD = "FILE_ADD";
    public static final String FILE_REMOVE = "FILE_REMOVE";
    public static final String FILE_CLEAR = "FILE_CLEAR";
    public static final String FILE_RESET = "FILE_RESET";

    private PhosideModelManager() {
        pcs = new PropertyChangeSupport(this);
        mapFileModels = new HashMap();
//        modelFiles = new LinkedHashMap();
    }

    public int modelFileCount() {
        return mapFileModels.size();
    }

    public Set<String> modelFiles() {
        return mapFileModels.keySet();
    }

    public boolean isModelFileLoaded(String file) {
        if (file==null) {
            throw new java.lang.IllegalArgumentException();
        }

        return mapFileModels.get(file)!=null;
    }

    public List<PhosideModel> loadModels(String file)
            throws IOException, ClassNotFoundException {
        if (file==null)
            return null;
        List<PhosideModel> models = mapFileModels.get(file);
        if (models==null) {
            Object obj = IOUtil.deserializeObject(file, "gz");
//            if (obj instanceof PhosideModel) {
//                models = new ArrayList();
//                models.add((PhosideModel)obj);
//            } else
            if (obj instanceof List) {
                models = (List<PhosideModel>)obj;
            } else {
                return null;
            }
            mapFileModels.put(file, models);
            for (PhosideModel m : models) {
                m.setFile(file);
            }
        }
        return models;
    }

    public void unloadModels(String file) {
        if (file==null)
            return;
        List<PhosideModel> models = mapFileModels.get(file);
        if (models!=null) {
            mapFileModels.put(file, null);
            models = null;
        }
    }

//    public String getModelFile(String name) {
//        if (name==null)
//            return null;
//        return modelFiles.get(name);
//    }

    public void addModelFile(String file)
            throws FileNotFoundException {
        addModelFile(file, null);
    }

    public void addModelFile(String file, List<PhosideModel> models)
            throws FileNotFoundException {
        if (file==null)
            return;

        if (!IOUtil.fileExist(file)) {
            throw new FileNotFoundException();
        }
        
        if (models!=null) {
            mapFileModels.put(file, new ArrayList<PhosideModel>(models));

            for (PhosideModel m : models) {
                m.setFile(file);
            }
        } else {
            mapFileModels.put(file, null);
        }


        pcs.firePropertyChange(FILE_ADD, null, models);
    }
//
//    public void saveModelsToFile(String file) throws IOException {
//        if (file==null)
//            return;
//
//        PhosideModel[] model = mapFileModels.get(file);
//        if (model!=null) {
//            phoside.util.IOUtil.serializeObject(model, file, "gz");
//        }
//    }

    public boolean removeModelFromFile(String file, PhosideModel model)
                throws IOException, ClassNotFoundException{
        if (file==null || model==null) {
            throw new IllegalArgumentException();
        }

        List<PhosideModel> models = loadModels(file);
        return models.remove(model);
    }

    public void removeModelFile(String file) {
        if (file==null) return;
        mapFileModels.remove(file);
//        IOUtil.deleteFile(file);
        pcs.firePropertyChange(FILE_REMOVE, file, null);
    }

    public void clear() {
        mapFileModels.clear();
        pcs.firePropertyChange(FILE_CLEAR, null, null);
    }

    public PropertyChangeSupport getPropertyChangeSupport() {
        return pcs;
    }
}
